﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pipes.Queries.Model.Query
{
  public class Identifier : IExpression
  {
    private bool[] _quoted;
    private string[] _parts;

    public bool Deterministic { get { return false; } }
    public Pipes.Queries.MetaData.GeneralDataType InferredType { get; set; }
    public IEnumerable<string> Parts
    {
      get
      {
        return _parts;
      }
    }

    public Identifier() 
    {
      _parts = new string[1];
      _quoted = new bool[] { false };
    }
    public Identifier(string value)
    {
      switch (value[0])
      {
        case '`':
        case '[':
        case '"':
        case '\'':
          _parts = new string[] { value.Substring(1, value.Length - 2) };
          _quoted = new bool[] { true };
          break;
        default:
          _parts = new string[] { value };
          _quoted = new bool[] { false };
          break;
      }
    }
    public Identifier(string value, Identifier remaining)
    {
      var newId = new Identifier(value);
      _parts = newId._parts.Union(remaining._parts).ToArray();
      _quoted = newId._quoted.Union(remaining._quoted).ToArray();
    }
    public Identifier(Identifier starting, string value)
    {
      var newId = new Identifier(value);
      _parts = starting._parts.Union(newId._parts).ToArray();
      _quoted = starting._quoted.Union(newId._quoted).ToArray();
    }

    public override string ToString()
    {
      return ToString('"', '.');
    }
    public string ToString(char quote, char delim)
    {
      var builder = new StringBuilder();
      for (var i = 0; i < _parts.Length; i++)
      {
        if (i > 0) builder.Append(delim);
        if (_quoted[i])
        {
          switch (quote)
          {
            case '`':
              builder.Append('`');
              builder.Append(_parts[i]);
              builder.Append('`');
              break;
            case '[':
              builder.Append('[');
              builder.Append(_parts[i]);
              builder.Append(']');
              break;
            case '\'':
              builder.Append('\'');
              builder.Append(_parts[i]);
              builder.Append('\'');
              break;
            case '\0':
              builder.Append(_parts[i]);
              break;
            default:
              builder.Append('"');
              builder.Append(_parts[i]);
              builder.Append('"');
              break;
          }
        }
        else
        {
          builder.Append(_parts[i]);
        }
      }
      return builder.ToString();
    }

    public void Visit(Parser.IQueryVisitor visitor)
    {
      visitor.Visit(this);
    }

    public object Evaluate()
    {
      throw new NotImplementedException();
    }
  }
}
